#include <GPSListener.h>
#include <stdint.h>

bool GPSListener::gpsNewFrameNMEA(char c)
{
    static char gps_frame_data[64]{0};
    static uint8_t data_size = 0;

    switch (c)
    {

    case '$':
        memset(gps_frame_data, 0, sizeof(gps_frame_data));
        data_size = 0;
        gps_frame_data[data_size++] = '$';

        break;

    // case '\r':
    case '\n':
    {
        if (data_size == 0)
            break;
        gps_frame_data[data_size++] = c;
        std::string_view frame_str = std::string_view(gps_frame_data, data_size);

        if (ofs.is_open())
            ofs.write(gps_frame_data, data_size);

        if (frame_str.substr(0, 6) == "$GNGGA")
        {
            auto gps = gps_data_parse(frame_str.data(), frame_str.size());
            if (gps.gga_data.quality)
            {
                m_gga = gps.gga_data;
            }
        }
        memset(gps_frame_data, 0, sizeof(gps_frame_data));
        data_size = 0;
        break;
    }

    default:
        if (gps_frame_data[0] == '$')
            gps_frame_data[data_size++] = c;
        break;
    }

    return false;
}

void GPSListener::onReadEvent(const char *portName, unsigned int readBufferLen)
{
    try
    {

        if (readBufferLen > 0)
        {
            auto data = std::vector<char>(readBufferLen);

            int recLen = p_sp->readData(data.data(), readBufferLen);

            if (recLen > 0)
            {
                data[recLen] = '\0';
                for (int i = 0; i < recLen; i++)
                {
                    gpsNewFrameNMEA(data[i]);
                }
            }
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "error:" << e.what() << '\n';
    }
    catch (const char *e)
    {
        std::cerr << "error:" << e << '\n';
    }
    catch (const int e)
    {
        std::cerr << "error:" << e << '\n';
    }
};

void GPSListener::onHotPlugEvent(const char *portName, int isAdd)
{
    // printf("portName: %s, isAdded: %d\n", portName, isAdd);
    m_availablePortsList = itas109::CSerialPortInfo::availablePortInfos();
    int availablePortCount = (int)m_availablePortsList.size();
    printf("\n\nAvailableFriendlyPorts:\n");
    for (int i = 1; i <= availablePortCount; ++i)
    {
        itas109::SerialPortInfo serialPortInfo = m_availablePortsList[i - 1];
        printf("%d - %s %s %s\n", i, serialPortInfo.portName, serialPortInfo.description, serialPortInfo.hardwareId);
    }
    printf("Please Input The Index Of Port(1 - %d)\n", availablePortCount);
}
